import br.unicarioca.viaexpositus.*;

class BootStrap {

    def authenticateService
    def grailsApplication
    def init = { servletContext ->

        def user = Usuario.find("from Usuario u where u.id=1")
        if(!user){
            try {
                println "Criando Status"
                criarStatus()
                println "Criando Tipode de Avaliação"
                criarTiposDeAvaliacao()
                println "Criando Estados"
                criarEstados()
                println "Criando Perfil"
                criarPerfil()
                println "Criando ou atualizando ações do administrador"
                criarTodasPermissoesParaAdmininstrador()
                println "Criando Organização"
                criarOrganizacao()
                println "Criando Usuário Administrador"
                criarUsuario()
            }catch(Exception e){
                e.printStackTrace()
            }
        }

        println "Criando ou atualizando ações do administrador"
        criarTodasPermissoesParaAdmininstrador()
        
        println "Criando Mapa de ações"
        buscarAcoes(servletContext)
    }

    def destroy = {

    }

    /**
     * Busca as ações dos controllers com a anotação.
     */
    def buscarAcoes(def servletContext){
        def  mapa = [:]
        grailsApplication.controllerClasses.each() { controller->

            def acoes = [:]
            controller.getClazz().getDeclaredFields().each{ campoDeclarado ->
                if(campoDeclarado.isAnnotationPresent(AnotacaoDeAcao)) {
                  def nomeDaAcao = campoDeclarado.getAnnotation(AnotacaoDeAcao).nomeDaAcao()
                  acoes[campoDeclarado.name] = nomeDaAcao
                }
            }

            mapa[controller.logicalPropertyName] = acoes
        }

        servletContext.mapaDeAcoes = mapa
    }

    def criarStatus(){
        def status = [
                [nome:"Acessível", descricao:"Status acessível"],
                [nome:"Inacessível", descricao:"Status inacessível"]
        ]
        status.each{map ->
            if(!StatusAvaliacao.findByNome(map["nome"])){
                new StatusAvaliacao(map).save(failOnError:true)
            }
        }
    }

    def criarTiposDeAvaliacao(){
        def tipos = [
                [nome:"Humana", descricao:"Avaliação de página realizada por um ser humano."],
                [nome:"Software", descricao:"Avaliação de página realizada por um software."]
        ]
        tipos.each{map ->
            if(!TipoDeAvaliacao.findByNome(map["nome"])){
                new TipoDeAvaliacao(map).save(failOnError:true)
            }
        }
    }

    def criarOrganizacao(){
        Organizacao org = new Organizacao()
        org.nome = "Via Expositus"
        org.cidade="Rio de Janeiro"
        org.estado = Estado.findByUf("RJ")
        org.endereco = "Rua Sem Saída"
        org.telefone = "7756-4567"
        org.cnpj = "1234567890"

        def usuarioInstance = new Usuario()
        usuarioInstance.nome = "Adm Org."
        usuarioInstance.email = "adm@adm.com"
        usuarioInstance.ativo = true
        usuarioInstance.senha = authenticateService.encodePassword("1234")
        usuarioInstance.confirmacaoSenha = authenticateService.encodePassword("1234")

        def perfil = Perfil.findByNome(Perfil.PERFIL_ORGANIZACAO)

        Perfil novoPerfil = new Perfil()
        novoPerfil.listaDePermissoes = []
        novoPerfil.nome = org.nome
        novoPerfil.descricao = "Este é o perfil do administrador da organização."
        novoPerfil.gerarCodeNome()

        perfil.listaDePermissoes.each{
            it.perfil = it.perfil+","+novoPerfil.codenome
            novoPerfil.listaDePermissoes << it
        }

        novoPerfil.save(failOnError:true)

        usuarioInstance.perfis = []
        usuarioInstance.perfis << novoPerfil

        usuarioInstance.organizacao = org

        novoPerfil.usuarios = []
        novoPerfil.addToUsuarios(usuarioInstance)

        org.administrador = usuarioInstance
        usuarioInstance.save(failOnError:true)
        org.save(failOnError:true)
    }

    def criarPerfil(){
        Perfil perfil = new Perfil()
        perfil.nome = "Administrador"
        perfil.descricao = "Este é o perfil do administrador geral do sistema."
        perfil.gerarCodeNome()
        perfil.save(failOnError:true, flush:true)

        Perfil perfil2 = new Perfil()
        perfil2.nome = "Organização"
        perfil2.descricao = "Este é o perfil da organização do sistema."
        perfil2.gerarCodeNome()
        perfil2.save(failOnError:true, flush:true)
    }


    /**
     * Cria e atualiza as permissões do administrador.
     */
    def criarTodasPermissoesParaAdmininstrador(){

        Perfil perfil = Perfil.findByNome("Administrador")
        Perfil perfil2 = Perfil.findByNome("Organização")

        if(perfil && !perfil.listaDePermissoes){
            perfil.listaDePermissoes = []
            perfil2.listaDePermissoes = []
        }

        grailsApplication.controllerClasses.each() { controller->
            controller.getClazz().getDeclaredFields().each{ campoDeclarado ->
                if(campoDeclarado.isAnnotationPresent(AnotacaoDeAcao)) {
                    def temPerfil = perfil.listaDePermissoes.find{it.url=="/${controller.logicalPropertyName}/${campoDeclarado.name}/**" && it.perfil.contains("ROLE_ADMINISTRADOR")}
                    if(!temPerfil){
                        def padrao = campoDeclarado.getAnnotation(AnotacaoDeAcao).padrao()
                        def perm = new Permissao(url:"/${controller.logicalPropertyName}/${campoDeclarado.name}/**", perfil : padrao)
                        if(padrao.contains("ROLE_ADMINISTRADOR")){
                            perfil.listaDePermissoes << perm
                        }
                        if(padrao.contains("ROLE_ORGANIZACAO")){
                            perfil2.listaDePermissoes << perm
                        }
                    }
                }
            }
        }

        perfil.save(failOnError:true)
        perfil2.save(failOnError:true)

    }

    def criarUsuario(){

        Perfil perfil = Perfil.findByNome("Administrador")

        Usuario usuario = new Usuario()
        usuario.nome = "Admin"
        usuario.senha = authenticateService.encodePassword("admin")
        usuario.confirmacaoSenha = authenticateService.encodePassword("admin")
        usuario.email = "via@expositus.com.br"
        usuario.perfis = []
        usuario.perfis.add(perfil)
        usuario.organizacao = null
        usuario.ativo = true
        usuario.save(failOnError:true)

        perfil.addToUsuarios(usuario)

    }
    
    def criarEstados(){
    	if(Estado.count()>0)
    		return 
    		
    	Estado estado 
    	estado = new Estado(nome:"Acre",uf:"AC") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Alagoas",uf:"AL") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Amapá",uf:"AP") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Amazonas",uf:"AM") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Bahia",uf:"BA") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Ceará",uf:"CE") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Distrito Federal",uf:"DF") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Espírito Santo",uf:"ES") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Goiás",uf:"GO") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Maranhão",uf:"MA") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Mato Grosso",uf:"MT") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Mato Grosso do Sul",uf:"MS") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Minas Gerais",uf:"MG") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Pará",uf:"PA") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Paraíba",uf:"PB") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Paraná",uf:"PR") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Pernambuco",uf:"PE") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Piauí",uf:"PI") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Rio de Janeiro",uf:"RJ") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Rio Grande do Norte",uf:"RN") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Rio Grande do Sul",uf:"RS") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Rondônia",uf:"RO") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Roraima",uf:"RR") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Santa Catarina",uf:"SC") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"São Paulo",uf:"SP") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Sergipe",uf:"SE") 
    	estado.save(failOnError:true)
    	estado = new Estado(nome:"Tocantins",uf:"TO") 
    	estado.save(failOnError:true)
    }
    
} 